﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using BEPUphysics.Entities;
using BEPUphysics.Entities.Prefabs;
using BEPUphysics;

namespace Brain.Bepu
{
    public class PhysicObject_Box : IPhysicsObject3D
    {
        public void Dispose()
        {
            this.Space.Remove(this.Box);
        }

        public float Width
        {
            get
            {
                return Box.Width;
            }
            set
            {
                Box.Width = value;
            }
        }
        public float Height
        {
            get
            {
                return Box.Height;
            }
            set
            {
                Box.Height = value;
            }
        }
        public float Length
        {
            get
            {
                return Box.Length;
            }
            set
            {
                Box.Length = value;
            }
        }

        public Box Box;

        public Vector3 Scale
        {
            get
            {
                return new Vector3(Width, Height, Length);
            }
            set
            {
                Width = value.X;
                Height = value.Y;
                Length = value.Z;
            }
        }

        public Quaternion Orientation
        {
            get { return Box.Orientation; }
            set { Box.Orientation = value; }
        }

        public object Tag { get; set; }

        public Vector3 Position
        {
            get { return Box.Position; }
            set { Box.Position = value; }
        }

        public bool Immovable
        {
            get { return !Box.IsDynamic; }
            set
            {
                if (value)
                {
                    Box.BecomeKinematic();
                }
                else
                {
                    Box.BecomeDynamic(1);
                }
            }
        }

        public float Mass
        {
            get { return Box.Mass; }
            set { Box.Mass = value; }
        }

        public Vector3 RotationRadians
        {
            get { return Vector3.Zero; }
            set { Orientation = QuaternionUtil.CreateQuaternion(value); }
        }

        public Space Space;

        public PhysicObject_Box(Space space)
            : base()
        {
            ShouldSerialize = true;
            this.Space = space;
            this.Box = new Box(Vector3.Zero, 1, 1, 1, 5);
            space.Add(this.Box);
            this.Immovable = false;
            this.Mass = 1;
            this.Tag = this.Box;
            this.Box.Tag = this;

            Box.PositionUpdated += new Action<Entity>(Box_PositionUpdated);
        }

        public void Box_PositionUpdated(Entity obj)
        {
            if (OnUpdate != null)
            {
                OnUpdate();
            }
        }

        public event SetVoid OnUpdate;


        public Vector3 LinearVelocity
        {
            get
            {
                return Box.LinearVelocity;
            }
            set
            {
                Box.LinearVelocity = value;
            }
        }
        public Vector3 AngularVelocity
        {
            get
            {
                return Box.AngularVelocity;
            }
            set
            {
                Box.AngularVelocity = value;
            }
        }

        public bool ShouldSerialize { get; set; }

        public void SerializeData(SerializationData parentData, string index)
        {
            // We do NOT need to serialize Position/Scale:
            // Position : The WorldObject parent of this PhysicsObject will save the Position
            // Scale    : The WorldObject has an Offset for setting this Scale

            parentData.AddData("PO.Rotation", this.Orientation, index);
            parentData.AddData("PO.Immovable", this.Immovable, index);
            parentData.AddData("PO.Name", this.Box.BrainIdentifier, index);
        }

        public void DeserializeData(SerializationData parentData, string index)
        {
            this.Orientation = parentData.GetData<Quaternion>("PO.Rotation", index);
            this.Immovable = parentData.GetData<bool>("PO.Immovable", index);
            this.Box.BrainIdentifier = parentData.GetData<string>("PO.Name", index);
        }

        public void DeserializedAll()
        {
        }
    }
}
